package com.cloudkinto.controller.order.allocate;


import com.cloudkinto.base.BaseController;
import com.cloudkinto.bo.order.allocate.*;
import com.cloudkinto.bo.order.outbound.ExceptionConfirmBo;
import com.cloudkinto.bo.stock.ProductStockBySkuQueryBo;
import com.cloudkinto.common.annotations.UserSessionRequired;
import com.cloudkinto.common.web.PageResult;
import com.cloudkinto.common.web.SingleResult;
import com.cloudkinto.service.order.allocate.AllocatePlanService;
import com.cloudkinto.service.order.outbound.OutboundImportExportService;
import com.cloudkinto.vo.order.allocate.AllocatePickingDetail;
import com.cloudkinto.vo.order.allocate.AllocatePlanBatchVo;
import com.cloudkinto.vo.order.allocate.ExceptionAllocateVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 调拨发货计划 前端控制器
 * </p>
 *
 * @author long
 * @since 2025-03-11
 */
@RestController
@RequiredArgsConstructor
@Api(tags = "Wms调拨发货计划模块")
@RequestMapping("/api/admin/wms/allocatePlan")
public class AllocatePlanWmsController extends BaseController {

    private final AllocatePlanService allocatePlanService;

    private final OutboundImportExportService outboundImportExportService;

    @UserSessionRequired
    @PutMapping("/update")
    @ApiOperation(value = "调拨发货计划修改", notes = "调拨发货计划修改")
    public SingleResult update(@RequestBody @Validated AllocatePlanUpdateBo req) {
        allocatePlanService.update(req, getCurrentUserId(), getUserName());
        return SingleResult.success("修改成功");
    }

    @UserSessionRequired
    @PostMapping("/detail")
    @ApiOperation(value = "调拨发货计划根据id查看详情", notes = "调拨发货计划根据id查看详情")
    @ApiResponses(@ApiResponse(code = 200, message = "", response = AllocatePlanBatchVo.class))
    public SingleResult<AllocatePlanBatchVo> detail(@RequestBody @Validated AllocatePlanDetailBo detail) {
        ProductStockBySkuQueryBo productStockBySkuQueryBo = new ProductStockBySkuQueryBo();
        productStockBySkuQueryBo.setStockAttribute(0);
        productStockBySkuQueryBo.setCompanyIdList(Collections.singletonList(getCompanyId()));
        productStockBySkuQueryBo.setSource("wms");
        productStockBySkuQueryBo.setTenantId(getTenantId());
        productStockBySkuQueryBo.setUserId(getCurrentUserId());
        productStockBySkuQueryBo.setWhId(getWarehouseId());
        return SingleResult.success("查询成功", allocatePlanService.detail(detail, productStockBySkuQueryBo));
    }

    @UserSessionRequired
    @GetMapping("/pageInit")
    @ApiOperation(value = "调拨发货计划查询初始化", notes = "调拨发货计划查询初始化")
    public SingleResult<Map<String, Object>> pageInit() {
        return allocatePlanService.pageInit(getCurrentUserId(), getTenantId(), getCompanyId(), "wms");
    }

    @UserSessionRequired
    @PostMapping("/listPage")
    @ApiOperation(value = "调拨批量发货计划查询（分页）", notes = "调拨批量发货计划查询（分页）")
    @ApiResponses(@ApiResponse(code = 200, message = "查询成功", response = AllocatePlanBatchVo.class))
    public PageResult<AllocatePlanBatchVo> listPage(@RequestBody @Validated AllocatePlanQueryBo bo) {
        bo.setWhId(getWarehouseId());
        bo.setTenantId(getTenantId());
        bo.setUserId(getCurrentUserId());
        bo.setSource("wms");
        return allocatePlanService.getListPage(bo);
    }

    @UserSessionRequired
    @PostMapping("/listPageStatusSta")
    @ApiOperation(value = "调拨批量发货计划查询分页统计", notes = "调拨批量发货计划查询分页统计")
    public SingleResult<List<Map<String, Object>>> listPageStatusSta(@RequestBody @Validated AllocatePlanQueryBo bo) {
        bo.setWhId(getWarehouseId());
        bo.setTenantId(getTenantId());
        bo.setUserId(getCurrentUserId());
        bo.setSource("wms");
        return allocatePlanService.getListPageStatusSta(bo);
    }

    @UserSessionRequired
    @PutMapping("/allocateSubmitPick")
    @ApiOperation(value = "调拨提交拣货", notes = "调拨提交拣货")
    public SingleResult allocateSubmitPick(@RequestParam("ids") Long[] ids) {
        return allocatePlanService.allocateSubmitPick(Arrays.asList(ids), getCurrentUserId(), getUserName());
    }

    @UserSessionRequired
    @GetMapping("/allocatePickingDetailInit")
    @ApiOperation(value = "调拨拣货详情初始化", notes = "调拨拣货详情初始化")
    public SingleResult<Map<String, Object>> allocatePickingDetailInit() {
        return SingleResult.success("查询成功", allocatePlanService.allocatePickingDetailInit(getCurrentUserId(), getTenantId(), "wms"));
    }

    @UserSessionRequired
    @GetMapping("/allocatePickingDetail/{id}")
    @ApiOperation(value = "调拨拣货详情", notes = "调拨拣货详情")
    @ApiResponses(@ApiResponse(code = 200, message = "", response = AllocatePickingDetail.class))
    public SingleResult<AllocatePickingDetail> allocatePickingDetail(@PathVariable("id") Long id) {
        return SingleResult.success("查询成功", allocatePlanService.allocatePickingDetail(id));
    }

    @UserSessionRequired
    @PostMapping("/allocatePicking")
    @ApiOperation(value = "调拨拣货", notes = "调拨拣货")
    @ApiResponses(@ApiResponse(code = 200, message = "true 完全拣货 false 部分拣货"))
    public SingleResult<Boolean> allocatePicking(@RequestBody @Validated AllocatePickingBo bo) {
        return SingleResult.success("拣货成功", allocatePlanService.allocatePicking(bo, getCurrentUserId(), getUserName(), getTenantId()));
    }

    @UserSessionRequired
    @PutMapping("/allocateOutboundOperation/{id}")
    @ApiOperation(value = "调拨出库操作（单个）", notes = "调拨出库操作（单个）")
    public SingleResult allocateOutboundOperation(@PathVariable(value = "id") Long id) {
        return allocatePlanService.allocateOutboundOperation(id, getCurrentUserId(), getUserName());
    }

    @UserSessionRequired
    @PutMapping("/allocateOutboundOperationBatch")
    @ApiOperation(value = "调拨出库操作(批量)", notes = "调拨出库操作(批量)")
    public SingleResult allocateOutboundOperationBatch(@RequestParam("ids") Long[] ids) {
        return allocatePlanService.allocateOutboundOperationBatch(Arrays.asList(ids), getCurrentUserId(), getUserName());
    }

    @UserSessionRequired
    @PutMapping("/markException/{id}")
    @ApiOperation(value = "调拨标记异常", notes = "调拨标记异常")
    public SingleResult markException(@PathVariable("id") Long id) {
        return allocatePlanService.markException(id, getCurrentUserId(), getUserName());
    }

    @UserSessionRequired
    @PostMapping("/exceptionOrderPageList")
    @ApiOperation(value = "调拨异常件", notes = "调拨异常件")
    @ApiResponses(@ApiResponse(code = 200, message = "", response = ExceptionAllocateVo.class))
    public PageResult exceptionOrderPageList(@RequestBody @Validated ExceptionAllocateQueryBo bo) {
        bo.setTenantId(getTenantId());
        return allocatePlanService.exceptionOrderPageList(bo);
    }

    @UserSessionRequired
    @PutMapping("/removeException/{id}")
    @ApiOperation(value = "调拨移除异常", notes = "调拨移除异常")
    public SingleResult removeException(@PathVariable("id") Long id) {
        return allocatePlanService.removeException(id, getCurrentUserId(), getUserName());
    }

    @UserSessionRequired
    @PutMapping("/exceptionConfirm")
    @ApiOperation(value = "调拨确认异常", notes = "调拨确认异常")
    public SingleResult exceptionConfirm(@RequestBody @Validated ExceptionConfirmBo bo) {
        return allocatePlanService.exceptionConfirm(bo, getCurrentUserId(), getUserName());
    }

    @UserSessionRequired
    @GetMapping("/printAllocateShippingList/{id}")
    @ApiOperation(value = "打印调拨发货清单", notes = "打印调拨发货清单")
    public void printAllocateShippingList(@PathVariable("id") Long id, HttpServletResponse response) throws Exception {
        outboundImportExportService.printAllocateShippingList(id, response);
    }

    @UserSessionRequired
    @GetMapping("/printAllocatePickingList/{id}")
    @ApiOperation(value = "调拨打印拣货清单", notes = "调拨打印拣货清单")
    public void printAllocatePickingList(@PathVariable("id") Long id, HttpServletResponse response) throws Exception {
        outboundImportExportService.printAllocatePickingList(id, response);
    }

    @UserSessionRequired
    @PostMapping("/allocateExportBy3rdWh")
    @ApiOperation(value = "调拨发货计划导出三方仓", notes = "调拨发货计划导出三方仓")
    public void allocateExportBy3rdWh(@RequestBody @Validated AllocatePlanQueryBo bo, HttpServletResponse response) throws IOException {
        bo.setWhId(getWarehouseId());
        bo.setTenantId(getTenantId());
        bo.setUserId(getCurrentUserId());
        bo.setSource("wms");
        outboundImportExportService.allocateExportBy3rdWh(bo, response);
    }

    @UserSessionRequired
    @PostMapping("/allocateExportByFba")
    @ApiOperation(value = "调拨发货计划导出fba", notes = "调拨发货计划导出fba")
    public void allocateExportByFba(@RequestBody @Validated AllocatePlanQueryBo bo, HttpServletResponse response) throws IOException {
        bo.setWhId(getWarehouseId());
        bo.setTenantId(getTenantId());
        bo.setUserId(getCurrentUserId());
        bo.setSource("wms");
        outboundImportExportService.allocateExportByFba(bo, response);
    }
}